#ifndef CONSOLE_HPP_
#define CONSOLE_HPP_

#include <Mint/Types.h>
#include <Mint/Errors.h>
#include "Utils/String.h"

#if TRACE_DRIVERS_CONSOLE
#define CONSOLE_TRACE(x ...) TRACE( "Console: " x)
#else
#define CONSOLE_TRACE(x ...)
#endif

class Console : public ITextOutput
{
public:
    enum Types
    {
        TypeMono = 0,
        TypeColor,
    };

    enum Modes
    {
        Mode80x25 = 0,
        Mode80x50,
        Mode90x60
    };

    enum Colors
    {
        ColorBlack = 0,
        ColorBlue,
        ColorGreen,
        ColorCyan,
        ColorRed,
        ColorMagenta,
        ColorBrown,
        ColorWhite,
        ColorGray,
        ColorBrightBlue,
        ColorBrightGreen,
        ColorBrightCyan,
        ColorBrightRed,
        ColorBrightMagenta,
        ColorBrightYellow,
        ColorBrightWhite,

        BrightColorMask = 0x08,
    };

public:
	Result Initialize( void );
	void SetPosition( uint8 x, uint8 y );
	void SetBackground( Colors color );
	void SetForeground( Colors color );
	void Clear( void );
	void MoveUp( void );
	void Write( char character );
	void Write( const char * message, ... );
	void UpdateCursor( void );
	uint8 GetAttributes( void ) { return fAttributes; };
	void SetAttributes( uint8 attributes ) { fAttributes = attributes; }
	void ChangeMode( Modes mode );

	uint8 GetWidth( void ) { return fWidth; };
	uint8 GetHeight( void ) { return fHeight; };
	uint8 GetX( void ) { return fPosition % fWidth; }
	uint8 GetY( void ) { return fPosition / fHeight; }

private:
    static bool __PutCharacter( char character, void * cookie );
	void _PutCharacter( char character );
	void _SetMode( uint8 * data );
	void _SetFont( uint8 * data, uint8 height );

private:
	Types		fType;
	Modes		fMode;
	Address		fMemoryAddress;
	uint16		fPort;
	uint8		fWidth;
	uint8		fHeight;
	uint8		fAttributes;
	uint32		fPosition;
	uint32		fLength;
};

extern Console sConsole;

#endif /*CONSOLE_HPP_*/
